﻿package MySQL
{
	import com.junkbyte.console.Cc;
	
	import Core.Game;
	import GameUtils.GameDataEvent;
	import Cryptos.AES;	
	import Cryptos.Base64;
	import Core.PlayerInfo;
	
	import flash.events.EventDispatcher;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.events.Event;
	import flash.utils.ByteArray;	
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;

	public class MySQLProvider extends EventDispatcher
	{		
		//Events
		public const PROFILES_LOADED:String = 'PROFILES_LOADED';
		public const PLAYER_INFO_LOADED:String = 'PLAYER_INFO_LOADED';		
		public const PROFILE_UPDATED:String = 'PROFILE_UPDATED';		
		//URLs
		private const CGetPlayer:String = 'getPlayer.php';
		private const CGetPlayers:String = 'getPlayers.php';
		private const CMySQLRequest:String = 'doRequest.php';
		private const CAESKey:String = 'UseTheForceLukeS234v775fasf';
		//Main loader
		private var FPlayerLoader:URLLoader;
		private var FGame:Game;
		
		public function MySQLProvider(AGame:Game):void 
		{
			FGame = AGame;
			FPlayerLoader = new URLLoader();			
		}
		
		// Player profile loading
		
		public function LoadPlayerInfo(AUID:String):void
		{
			var vRequest:String = FGame.Settings.ScriptsDirectory + CGetPlayer + '?uid=' + AUID;
			FPlayerLoader.load(new URLRequest(vRequest));
			FPlayerLoader.addEventListener(Event.COMPLETE, OnPlayerData);
			FPlayerLoader.addEventListener(IOErrorEvent.IO_ERROR, OnIOError);
			FPlayerLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, OnSecurityError);
		}
		
		private function OnIOError(e:IOErrorEvent):void
		{
			FGame.ShowError('Ошибка при обращении к базе данных: ' + e.text);
		}
		
		private function OnSecurityError(e:SecurityErrorEvent):void
		{
			FGame.ShowError('Ошибка при обращении к базе данных: ' + e.text);
		}
		
		private function OnPlayerData(e:Event):void
		{
			var vEncoded:String = String(e.target.data);			
			var vXML:XML = XML(Decrypt(vEncoded));			
			var vUID:String = vXML.player.@uid;
			FPlayerLoader.removeEventListener(Event.COMPLETE, OnPlayerData);
			
			if(vUID != '')
			{
				DispatchDataEvent(PLAYER_INFO_LOADED, vXML);
			}
			else
			{
				AddNewPlayer(FGame.UserID);
			}
		}
		
		// Player profile adding
		
		private function AddNewPlayer(AUID:String):void
		{
			var vQuery:String = '';			
			vQuery += Format(AUID);
			vQuery += Format(FGame.User.Name);
			//money
			vQuery += Format('0');
			//rating
			vQuery += Format('1500');
			//player's items
			vQuery += Format('-1');			
			//currently setted items
			//skin;visualization;dynamics,equalizer,headphones,amplifier,vinil;wins,loses;time
			vQuery += Format(FGame.Settings.DefaultSkin + ';0;-1,-1,-1,-1,-1;0,0;0', true);
			vQuery = MakeInsertRequest(vQuery);
			
			var vRequest:String = FGame.Settings.ScriptsDirectory + CMySQLRequest + '?query=' + Encrypt(vQuery);
			FPlayerLoader.load(new URLRequest(vRequest));
			FPlayerLoader.addEventListener(Event.COMPLETE, OnPlayerAdded);
		}
		
		private function OnPlayerAdded(e:Event):void
		{
			var vDefaultSettings:String = FGame.Settings.DefaultSkin + ';0;-1,-1,-1,-1,-1;0,0;0';
			var vXML:XML = <players></players>;
			vXML.appendChild(<player uid = {FGame.UserID} name={FGame.User.Name} money="0" rating="1500" items="-1" settings={vDefaultSettings}/>);			
			trace('New player added: ');
			trace(vXML.toString());			
			DispatchDataEvent(PLAYER_INFO_LOADED, vXML);			
		}
		
		private function MakeInsertRequest(AParams:String):String
		{
			return 'INSERT INTO users VALUES (NULL, ' + AParams + ');';
		}
		
		// Player profile updating
		
		public function UpdateProfile(AUser:PlayerInfo):void
		{
			var vParams:String = new String();
			vParams += 'name = ' + Format(AUser.Name);
			vParams += 'money = ' + Format(AUser.Money.toString());
			vParams += 'rating = ' + Format(AUser.Rating.toString());
			vParams += 'items = ' + Format(AUser.Items.toString());
			vParams += 'settings = ' + '"' + AUser.Settings + '"';
			
			var vQuery:String = MakeUpdateRequest(vParams);
			
			var vRequest:String = FGame.Settings.ScriptsDirectory + CMySQLRequest + '?query=' + Encrypt(vQuery);
			FPlayerLoader.load(new URLRequest(vRequest));
			FPlayerLoader.addEventListener(Event.COMPLETE, OnProfileUpdated);
		}
		
		private function MakeUpdateRequest(AParams:String):String
		{
			return 'UPDATE users SET ' + AParams + ' WHERE uid = "' + FGame.UserID + '"';			
		}
		
		private function OnProfileUpdated(e:Event):void
		{
			dispatchEvent(new Event(PROFILE_UPDATED));
		}
		
		private function Format(AParam:String, AFinal:Boolean = false):String
		{
			if(!AFinal)
			{
				return '"' + AParam + '", '
			}
			else
			{
				return '"' + AParam + '"';
			}
		}
		
		// TOP - 100 list loading
		
		public function LoadTop100():void
		{
			var vLoader:URLLoader = new URLLoader();
			vLoader.addEventListener(Event.COMPLETE, OnTop100Loaded);
			vLoader.load(new URLRequest(FGame.Settings.ScriptsDirectory + CGetPlayers));			
		}
		
		private function OnTop100Loaded(e:Event):void
		{			
			DispatchDataEvent(PROFILES_LOADED, e.target.data)
		}
				
		private function Encrypt(APlain:String):String
        {
			return Base64.encode(AES.encrypt(APlain, CAESKey, AES.BIT_KEY_256));
        }

        private function Decrypt(AEncoded:String):String
        {
            return Base64.decode(AES.decrypt(AEncoded, CAESKey, AES.BIT_KEY_256));
        }
		
		private function DispatchDataEvent(AType:String, AData:Object):void
		{
			var vEvent:GameDataEvent = new GameDataEvent(AType);
			vEvent.Data = AData;
			dispatchEvent(vEvent);
		}
		
		//
	}	
}
